﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Reflection;
using MessagePack.Formatters;

namespace MessagePack.Internal
{
	// Token: 0x0200010D RID: 269
	internal static class DynamicGenericResolverGetFormatterHelper
	{
		// Token: 0x060003C8 RID: 968 RVA: 0x0000E148 File Offset: 0x0000C548
		internal static object GetFormatter(Type t)
		{
			TypeInfo_wzh typeInfo = t.GetTypeInfo_wzh();
			if (!t.IsArray)
			{
				if (typeInfo.IsGenericType)
				{
					Type genericTypeDefinition = typeInfo.GetGenericTypeDefinition();
					TypeInfo_wzh typeInfo2 = genericTypeDefinition.GetTypeInfo_wzh();
					bool flag = typeInfo2.IsNullable();
					Type type = (!flag) ? null : typeInfo.GenericTypeArguments[0];
					if (genericTypeDefinition == typeof(KeyValuePair<, >))
					{
						return DynamicGenericResolverGetFormatterHelper.CreateInstance(typeof(KeyValuePairFormatter<, >), typeInfo.GenericTypeArguments, new object[0]);
					}
					if (flag && type.GetTypeInfo_wzh().IsConstructedGenericType() && type.GetGenericTypeDefinition() == typeof(KeyValuePair<, >))
					{
						return DynamicGenericResolverGetFormatterHelper.CreateInstance(typeof(NullableFormatter<>), new Type[]
						{
							type
						}, new object[0]);
					}
					if (genericTypeDefinition == typeof(ArraySegment<>))
					{
						if (typeInfo.GenericTypeArguments[0] == typeof(byte))
						{
							return ByteArraySegmentFormatter.Instance;
						}
						return DynamicGenericResolverGetFormatterHelper.CreateInstance(typeof(ArraySegmentFormatter<>), typeInfo.GenericTypeArguments, new object[0]);
					}
					else if (flag && type.GetTypeInfo_wzh().IsConstructedGenericType() && type.GetGenericTypeDefinition() == typeof(ArraySegment<>))
					{
						if (type == typeof(ArraySegment<byte>))
						{
							return new StaticNullableFormatter<ArraySegment<byte>>(ByteArraySegmentFormatter.Instance);
						}
						return DynamicGenericResolverGetFormatterHelper.CreateInstance(typeof(NullableFormatter<>), new Type[]
						{
							type
						}, new object[0]);
					}
					else
					{
						Type genericType;
						if (DynamicGenericResolverGetFormatterHelper.formatterMap.TryGetValue(genericTypeDefinition, out genericType))
						{
							return DynamicGenericResolverGetFormatterHelper.CreateInstance(genericType, typeInfo.GenericTypeArguments, new object[0]);
						}
						if (typeInfo.GenericTypeArguments.Length == 1)
						{
							if (typeInfo.ImplementedInterfaces.Any((Type x) => x.GetTypeInfo_wzh().IsConstructedGenericType() && x.GetGenericTypeDefinition() == typeof(ICollection<>)))
							{
								if (typeInfo.DeclaredConstructors.Any((ConstructorInfo x) => x.GetParameters().Length == 0))
								{
									Type type2 = typeInfo.GenericTypeArguments[0];
									return DynamicGenericResolverGetFormatterHelper.CreateInstance(typeof(GenericCollectionFormatter<, >), new Type[]
									{
										type2,
										t
									}, new object[0]);
								}
							}
						}
						if (typeInfo.GenericTypeArguments.Length == 2)
						{
							if (typeInfo.ImplementedInterfaces.Any((Type x) => x.GetTypeInfo_wzh().IsConstructedGenericType() && x.GetGenericTypeDefinition() == typeof(IDictionary<, >)))
							{
								if (typeInfo.DeclaredConstructors.Any((ConstructorInfo x) => x.GetParameters().Length == 0))
								{
									Type type3 = typeInfo.GenericTypeArguments[0];
									Type type4 = typeInfo.GenericTypeArguments[1];
									return DynamicGenericResolverGetFormatterHelper.CreateInstance(typeof(GenericDictionaryFormatter<, , >), new Type[]
									{
										type3,
										type4,
										t
									}, new object[0]);
								}
							}
						}
					}
				}
				return null;
			}
			int arrayRank = t.GetArrayRank();
			if (arrayRank == 1)
			{
				if (t.GetElementType() == typeof(byte[]))
				{
					return ByteArrayFormatter.Instance;
				}
				return Activator.CreateInstance(typeof(ArrayFormatter<>).MakeGenericType(new Type[]
				{
					t.GetElementType()
				}));
			}
			else
			{
				if (arrayRank == 2)
				{
					return Activator.CreateInstance(typeof(TwoDimentionalArrayFormatter<>).MakeGenericType(new Type[]
					{
						t.GetElementType()
					}));
				}
				if (arrayRank == 3)
				{
					return Activator.CreateInstance(typeof(ThreeDimentionalArrayFormatter<>).MakeGenericType(new Type[]
					{
						t.GetElementType()
					}));
				}
				if (arrayRank == 4)
				{
					return Activator.CreateInstance(typeof(FourDimentionalArrayFormatter<>).MakeGenericType(new Type[]
					{
						t.GetElementType()
					}));
				}
				return null;
			}
		}

		// Token: 0x060003C9 RID: 969 RVA: 0x0000E502 File Offset: 0x0000C902
		private static object CreateInstance(Type genericType, Type[] genericTypeArguments, params object[] arguments)
		{
			return Activator.CreateInstance(genericType.MakeGenericType(genericTypeArguments), arguments);
		}

		// Token: 0x04000165 RID: 357
		private static readonly Dictionary<Type, Type> formatterMap = new Dictionary<Type, Type>
		{
			{
				typeof(List<>),
				typeof(ListFormatter<>)
			},
			{
				typeof(LinkedList<>),
				typeof(LinkedListFormatter<>)
			},
			{
				typeof(Queue<>),
				typeof(QeueueFormatter<>)
			},
			{
				typeof(Stack<>),
				typeof(StackFormatter<>)
			},
			{
				typeof(HashSet<>),
				typeof(HashSetFormatter<>)
			},
			{
				typeof(ReadOnlyCollection<>),
				typeof(ReadOnlyCollectionFormatter<>)
			},
			{
				typeof(IList<>),
				typeof(InterfaceListFormatter<>)
			},
			{
				typeof(ICollection<>),
				typeof(InterfaceCollectionFormatter<>)
			},
			{
				typeof(IEnumerable<>),
				typeof(InterfaceEnumerableFormatter<>)
			},
			{
				typeof(Dictionary<, >),
				typeof(DictionaryFormatter<, >)
			},
			{
				typeof(IDictionary<, >),
				typeof(InterfaceDictionaryFormatter<, >)
			},
			{
				typeof(SortedDictionary<, >),
				typeof(SortedDictionaryFormatter<, >)
			},
			{
				typeof(SortedList<, >),
				typeof(SortedListFormatter<, >)
			},
			{
				typeof(ILookup<, >),
				typeof(InterfaceLookupFormatter<, >)
			},
			{
				typeof(IGrouping<, >),
				typeof(InterfaceGroupingFormatter<, >)
			}
		};
	}
}
